package org.openea.eap.module.obpm.service.form.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ClassUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.openbpm.base.api.exception.BusinessError;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.base.api.query.QueryFilter;
import org.openbpm.base.api.query.QueryOP;
import org.openbpm.base.core.id.IdUtil;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.base.db.model.query.DefaultQueryFilter;
import org.openbpm.base.manager.impl.BaseManager;
import org.openbpm.bus.api.constant.BusTableRelType;
import org.openbpm.bus.api.model.IBusTableRel;
import org.openbpm.bus.api.model.IBusinessObject;
import org.openbpm.bus.api.service.IBusinessObjectService;
import org.openbpm.form.api.constant.FormTemplateType;
import org.openbpm.form.api.model.FormType;
import org.openea.eap.module.obpm.dao.form.FormTemplateDao;
import org.openea.eap.module.obpm.model.form.FormTemplate;
import org.openea.eap.module.obpm.service.form.FormTemplateManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class FormTemplateManagerImpl
  extends BaseManager<String, FormTemplate>
  implements FormTemplateManager
{
  @Resource
  FormTemplateDao formTemplateDao;
  @Autowired
  IBusinessObjectService businessObjectService;

  @Value("${bpm.form.template.dirs:'pc_vue,mobile'}")
  private String templateDirs;

  public static String getFormTemplatePath() {
    try {
      return ClassUtil.getClassPath() + File.separator + "template" + File.separator + "form" + File.separator;
    } catch (Exception e) {
      throw new BusinessException(e);
    }
  }

  public FormTemplate getByKey(String key) {
    if (StringUtil.isEmpty(key)) return null;

    DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
    defaultQueryFilter.addFilter("key_", key, QueryOP.EQUAL);
    return (FormTemplate)queryOne((QueryFilter)defaultQueryFilter);
  }


  public void initAllTemplate() {
    DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
    defaultQueryFilter.addFilter("editable_", Boolean.valueOf(false), QueryOP.EQUAL);
    defaultQueryFilter.setPage(null);
    for (FormTemplate template : query((QueryFilter)defaultQueryFilter)) {
      remove(template.getId());
    }

    initTemplate();
  }


  public void init() {
    if (getAll().isEmpty()) {
      initTemplate();
    }
  }

  private void initTemplate() {

    try {
      Set<String> setTemplateDirs = new HashSet<String>();
      if(templateDirs==null || "".equals(templateDirs)){
        templateDirs = "pc_vue, mobile";
      }
      String[] tt = templateDirs.split(",");
      for(String dir: tt){
        setTemplateDirs.add(dir.trim());
      }
      String templatePath = "/template/formDef/";
      InputStream instream = getClass().getResourceAsStream(templatePath + "templates.xml");
      String xml = IOUtils.toString(instream, "UTF-8");
      Document document = DocumentHelper.parseText(xml);
      Element root = document.getRootElement();
      List<Element> list = root.elements();
      for (Element element : list) {
        String key = element.attributeValue("key");
        String name = element.attributeValue("name");
        String type = element.attributeValue("type");
        String desc = element.attributeValue("desc");
        String dir = element.attributeValue("dir");

        // 增加模板dir/过滤
        if(!setTemplateDirs.contains(dir)){
          continue;
        }

        String fileName = templatePath + dir + "/" + key + ".ftl";
        System.out.println(fileName);
        String html = IOUtils.toString(getClass().getResourceAsStream(fileName), "UTF-8");



        FormTemplate formTemplate = new FormTemplate();
        formTemplate.setId(IdUtil.getSuid());
        formTemplate.setHtml(html);
        formTemplate.setName(name);
        formTemplate.setKey(key);
        formTemplate.setEditable(false);
        formTemplate.setType(type);
        formTemplate.setFormType(dir);
        formTemplate.setDesc(desc);
        this.formTemplateDao.create(formTemplate);
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new BusinessException(e);
    }
  }




  public boolean isExist(String key) { return (getByKey(key) != null); }



  public void backUpTemplate(String id) {
    FormTemplate formTemplate = (FormTemplate)this.formTemplateDao.get(id);
    String alias = formTemplate.getKey();
    String name = formTemplate.getName();
    String desc = formTemplate.getDesc();
    String html = formTemplate.getHtml();
    String type = formTemplate.getType();

    String templatePath = getFormTemplatePath();

    String xmlPath = templatePath + "templates.xml";
    String xml = FileUtil.readUtf8String(xmlPath);
    Document document = null;
    try {
      document = DocumentHelper.parseText(xml);
    } catch (DocumentException e) {
      throw new BusinessError("解析文件出错", (Throwable)e);
    }
    Element root = document.getRootElement();

    Element e = root.addElement("template");
    e.addAttribute("alias", alias);
    e.addAttribute("name", name);
    e.addAttribute("type", type);
    e.addAttribute("templateDesc", desc);
    String content = document.asXML();

    FileUtil.writeUtf8String(content, xmlPath);
    FileUtil.writeUtf8String(html, templatePath + alias + ".ftl");

    formTemplate.setEditable(false);
    this.formTemplateDao.update(formTemplate);
  }

  public List<FormTemplate> getByType(String type, String formType, Boolean hasDesignForm) {
    DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
    defaultQueryFilter.setPage(null);
    defaultQueryFilter.addFilter("type_", type, QueryOP.EQUAL);
    defaultQueryFilter.addFilter("form_type_", formType, QueryOP.EQUAL);
    if (hasDesignForm.booleanValue()) {
      defaultQueryFilter.addFilter("type_", type.concat("FormOverallArrangement"), QueryOP.EQUAL);
    }
    return query((QueryFilter)defaultQueryFilter);
  }


  public JSONArray templateData(String boKey, String type) {
    IBusinessObject bo = this.businessObjectService.getByKey(boKey);
    if (bo == null) {
      throw new BusinessException(String.format("业务对象丢失，请检查业务对象：%s", new Object[] { boKey }));
    }
    boolean hasDesignForm = false;
    if (StringUtil.isNotEmpty(this.businessObjectService.getBoOverallArrangement(boKey)) && !FormType.MOBILE.value().equals(type)) {
      hasDesignForm = true;
    }
    List<IBusTableRel> rels = (List<IBusTableRel>) bo.getRelation().list();
    List<FormTemplate> mainTemplates = getByType(FormTemplateType.MAIN.getKey(), type, Boolean.valueOf(hasDesignForm));
    List<FormTemplate> subTableTemplates = getByType(FormTemplateType.SUB_TABLE.getKey(), type, Boolean.valueOf(hasDesignForm));
    for (FormTemplate template : mainTemplates) {
      template.setHtml(null);
    }
    for (FormTemplate template : subTableTemplates) {
      template.setHtml(null);
    }

    JSONArray jsonArray = new JSONArray();
    for (IBusTableRel rel : rels) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("tableKey", rel.getTableKey());
      jsonObject.put("tableComment", rel.getTableComment());
      jsonObject.put("typeDesc", BusTableRelType.getByKey(rel.getType()).getDesc());
      if (BusTableRelType.MAIN.equalsWithKey(rel.getType())) {
        jsonObject.put("templates", JSON.toJSON(mainTemplates));
      } else {
        jsonObject.put("templates", JSON.toJSON(subTableTemplates));
      }
      jsonArray.add(jsonObject);
    }

    return jsonArray;
  }
}
